package blog.network;

import java.util.*; //needed for Calendar and Date

/**
 * This class can be used to convert from Date to String and back.
 * This is only necessary because J2ME's Date class is significantly
 * different from J2SE's Date class, and because J2ME is missing
 * the DateFormat class.
 *
 */
public class DateConverter
{

	public static final int DATE = 1;

	public static final int TIME = 2;

	public static final int DATE_TIME = 3;

	public static final boolean debugOn = false;

	/**
	 * Writes an integer to the string buffer as
	 * a double digit, regardless of the value
	 * (e.g. the value 9 becomes "09")
	 * @param Buffer to which the string should be written.
	 * @param Value to be converted to two-digit string.
	 */
	protected static void twoDigit(StringBuffer buf, int val)
	{
		buf.append( (char) (((int) '0') + val / 10) );
		buf.append( (char) (((int) '0') + val % 10) );
	} //twoDigit

	/**
	 * Convert a java Date object into an IS0.8601-formatted String.
	 * This implementation complies with the XMLRPC specification 
	 * (and thus with Movable Type 2.5.1)-- it may not comply directly
	 * with ISO8601. 
	 * @param Date to be converted to a String
	 * @param The type of conversion: DATE_TIME for both date and time, or just DATE or TIME
	 * @return String representation of this Date
	 */
	public static String dateToIso8601String(Date date, int type)
	{
		int initLen;

		//to do any kind of Date to String conversion, we need a Calendar object
		Calendar cal = Calendar.getInstance( );
		//we assume that the user's device time zone has been set correctly
		cal.setTimeZone( TimeZone.getDefault( ) ); //current default for this device
		cal.setTime( date );

		//set up the initial length of the buffer to be the correct length
		switch (type)
		{
		case TIME:
		case DATE:
			initLen = 8; //YYYYMMDD  -or- HH:MM:SS
			break;
		case DATE_TIME:
		default:
			initLen = 17; //YYYYMMDDTHH:MM:SS
		}

		StringBuffer buf = new StringBuffer( initLen );

		if ((type & DATE) != 0)
		{
			//Write the date as YYYYMMDD
			int year = cal.get( Calendar.YEAR );
			twoDigit( buf, year / 100 ); //e.g. "20"
			twoDigit( buf, year % 100 ); //e.g. "02" ... "2002"
			twoDigit( buf, (cal.get( Calendar.MONTH ) - Calendar.JANUARY) + 1 );
			twoDigit( buf, cal.get( Calendar.DAY_OF_MONTH ) );

			//A "T" separates the date portion from the time portion of the string
			if (type == DATE_TIME)
				buf.append( "T" );
		}

		if ((type & TIME) != 0)
		{
			//For XMLRPC, this is just HH:MM:SS ...no time zone etc. ? using 24 hr clock?
			twoDigit( buf, cal.get( Calendar.HOUR_OF_DAY ) );
			buf.append( ':' );
			twoDigit( buf, cal.get( Calendar.MINUTE ) );
			buf.append( ':' );
			twoDigit( buf, cal.get( Calendar.SECOND ) );
		}

		return buf.toString( );
	} //dateToIso8601String

	/**
	 * Convert a date string to a Date object.
	 * We assume that the date string is in the same ISO.8601 format
	 * generated by the dateToIso8601String method:
	 * YYYYMMDDTHH:MM:SS
	 * @param The date string to be read.
	 * @param Type of string we think it is: DATE_TIME, or just DATE or TIME
	 */
	public static Date stringToDate(String dateStr, int type)
	{

		Calendar cal = Calendar.getInstance( ); //set to default time
		String timeStr = null;

		//clear the offsets
		if (type != DATE_TIME)
			cal.setTime( new Date( 0 ) );

		if ((type & DATE) != 0)
		{
			String curStr = dateStr.substring( 0, 4 );
			//if (debugOn) ("year: " + curStr);
			cal.set( Calendar.YEAR, Integer.parseInt( curStr ) );

			curStr = dateStr.substring( 4, 6 );
			//if (debugOn) ("month: " + curStr);
			cal.set( Calendar.MONTH, Integer.parseInt( curStr ) - 1
					+ Calendar.JANUARY );

			curStr = dateStr.substring( 6, 8 );
			//if (debugOn) ("day: " + curStr);
			cal.set( Calendar.DAY_OF_MONTH, Integer.parseInt( curStr ) );
		}

		//move the cursor forward
		switch (type)
		{
		case DATE_TIME:
			timeStr = dateStr.substring( 9 );
			break;
		case TIME:
			timeStr = dateStr;
			break;
		case DATE:
		default:
			//skip the rest if we're just interested in DATE
			return cal.getTime( );
		}

		cal.set( Calendar.HOUR_OF_DAY, Integer.parseInt( timeStr.substring( 0, 2 ) ) );
		cal.set( Calendar.MINUTE, Integer.parseInt( timeStr.substring( 3, 5 ) ) );
		cal.set( Calendar.SECOND, Integer.parseInt( timeStr.substring( 6, 8 ) ) );
		return cal.getTime( );
	}//stringToDate

}//class KDateConverter
